#include "unixhead.h"

#include <workflow/WFFacilities.h>
#include <workflow/WFHttpServer.h>

#include <iostream>
using namespace std;

static WFFacilities::WaitGroup waitGroup(1);

void sighandler(int signum)
{
    cout << "wait group done\n";
    (void)signum;
    waitGroup.done();
}

struct SeriesFileIOContext
{
    char * buff;
    int fd;
    size_t filesize;
    protocol::HttpResponse * resp;
};

void httpServerCallback(WFHttpTask * serverTask)
{
    cout << "htttServerCallback is running" << endl;
    auto context = static_cast<SeriesFileIOContext*>(series_of(serverTask)->get_context());
    delete [] context->buff;
    close(context->fd);
    delete context;
}

void IOCallback(WFFileIOTask * fileIOTask)
{
    cout << "IO callback is running\n";
    //运行到这里时，读操作已经读完了
    int state = fileIOTask->get_state();
    int error = fileIOTask->get_error();
    switch(state) {
    case WFT_STATE_SYS_ERROR:
        printf("system error: %s\n", strerror(error));break;
    case WFT_STATE_SUCCESS:
        break;
    }

    if(state != WFT_STATE_SUCCESS) {
        printf("fileio task occurs error!\n");
        return;
    }

    //获取数据
    auto context = static_cast<SeriesFileIOContext*>(
            series_of(fileIOTask)->get_context());
    context->filesize = fileIOTask->get_retval();
    cout << "filesize:" << context->filesize << endl;
    //生成响应
    context->resp->append_output_body_nocopy(context->buff, context->filesize);
    context->resp->add_header_pair("Content-Type", "text/html");
}

void process(WFHttpTask * serverTask)
{
    cout << "process function is running\n";
    int state = serverTask->get_state();
    int error = serverTask->get_error();
    cout << "state:" << state << endl;
    switch(state){
    case WFT_STATE_SYS_ERROR:
        fprintf(stderr, "system error: %s\n", strerror(error)); break;
    case WFT_STATE_NOREPLY:
        printf("state is WFT_STATE_NOREPLY\n"); break;
    }

    //接下来是要进行回复
    if(state != WFT_STATE_TOREPLY) {
        printf("error occurs!\n");
        return;
    }
    
    //获取uri, 解析请求
    auto req = serverTask->get_req();
    auto resp = serverTask->get_resp();
    string method = req->get_method();
    string path = req->get_request_uri();
    cout << "path:" << path << endl;

    if(method == "GET" && path == "/login") {
        //读取服务器本地的文件内容
        // /usr/local/nginx/html/postform.html
        int fd = open("/usr/local/nginx/html/postform.html", O_RDONLY);
        if(fd < 0) {
            perror("open");
            return;
        }
        char * buff = new char[1024]();
        
        auto fileIOTask = WFTaskFactory::create_pread_task(
            fd, buff, 1024, 0, IOCallback);
        series_of(serverTask)->push_back(fileIOTask);
        //设置共享数据
        auto context = new SeriesFileIOContext();
        context->buff = buff;
        context->fd = fd;
        context->filesize = 1024;
        context->resp = resp;
        series_of(serverTask)->set_context(context);
        serverTask->set_callback(httpServerCallback);
    }

}

int main()
{
    signal(SIGINT, sighandler);

    WFHttpServer server(process);

    //start的返回值监听成功返回值为0
    if(0 == server.start(8888)) {
        waitGroup.wait();
        server.stop();   
    } else {
        cout << "server start error!\n";
    }

    return 0;
}
